package com.basics.api.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import com.alibaba.fastjson.JSONObject;
import com.basics.api.enums.socket.MessageEnum;
import com.basics.api.response.channel.ChannelListData;
import com.basics.api.response.organization.DefaultOrganizationInfoData;
import com.basics.api.response.socket.MessageData;
import com.basics.api.vo.UserInfo;
import com.basics.car.service.*;
import com.basics.channel.entity.CyChannelMsg;
import com.basics.channel.service.*;
import com.basics.common.constant.BillLockConstant;
import com.basics.common.constant.Constants;
import com.basics.common.user.BillLockUtil;
import com.basics.common.utils.AsyncUtil;
import com.basics.common.utils.RandomUtils;
import com.basics.common.utils.SmsWhUtil;
import com.basics.common.utils.StringUtils;
import com.basics.common.utils.huawei.SendSms;
import com.basics.common.utils.redis.RedisUtil;
import com.basics.driver.service.*;
import com.basics.framework.constants.WxProperties;
import com.basics.framework.redission.RedissonDelayQueueClient;
import com.basics.framework.webSocket.ChatEndpoint;
import com.basics.organization.entity.CyOrganization;
import com.basics.organization.entity.CyOrganizationGroup;
import com.basics.organization.entity.CyOrganizationUser;
import com.basics.organization.service.CyOrganizationGroupService;
import com.basics.organization.service.CyOrganizationPermissionService;
import com.basics.organization.service.CyOrganizationService;
import com.basics.organization.service.CyOrganizationUserService;
import com.basics.phone.service.DmPhoneRetrievalService;
import com.basics.phone.service.DmPhoneService;
import com.basics.platform.service.DmPlatformGmvService;
import com.basics.platform.service.DmPlatformService;
import com.basics.post.service.CyChannelPostFileService;
import com.basics.post.service.CyChannelPostPriseService;
import com.basics.post.service.CyChannelPostService;
import com.basics.post.service.CyChannelPostUserService;
import com.basics.sys.service.DmTableSortService;
import com.basics.sys.service.SysDictItemService;
import com.basics.sys.service.SysDictService;
import com.basics.user.entity.CyAuth;
import com.basics.user.entity.CyUser;
import com.basics.user.service.CyAuthService;
import com.basics.user.service.CyUserService;
import com.basics.workorder.service.DmWorkOrderService;
import com.basics.workorder.service.DmWorkOrderTransferService;
import com.basics.workorder.service.DmWorkOrderTypeService;
import com.github.binarywang.wxpay.service.WxPayService;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 公共服务层
 * @Author WangWei
 * @Date 2021/11/10 12:28
 * @Version 2.0
 * @Description
 **/
@Component
public class BaseApiService {

    protected final Logger logger = LoggerFactory.getLogger(BaseApiService.class);

    @Value("${spring.profiles.active}")
    protected String active;

    @Autowired
    protected RedisTemplate<String, Object> redisTemplate;
    @Autowired
    protected RedisUtil redisUtil;

    @Autowired
    protected WxMaService wxMaService;

    @Autowired
    protected WxPayService wxPayService;

    @Autowired
    protected CyAuthService cyAuthService;
    @Autowired
    protected CyUserService cyUserService;
    @Autowired
    protected CyOrganizationGroupService cyOrganizationGroupService;
    @Autowired
    protected CyOrganizationPermissionService cyOrganizationPermissionService;
    @Autowired
    protected CyOrganizationService cyOrganizationService;
    @Autowired
    protected CyOrganizationUserService cyOrganizationUserService;
    @Autowired
    protected CyChannelCommentPriseService cyChannelCommentPriseService;
    @Autowired
    protected CyChannelCommentService cyChannelCommentService;
    @Autowired
    protected CyChannelGroupPermissionService cyChannelGroupPermissionService;
    @Autowired
    protected CyChannelGroupService cyChannelGroupService;
    @Autowired
    protected CyChannelGroupUserService cyChannelGroupUserService;
    @Autowired
    protected CyChannelMsgService cyChannelMsgService;
    @Autowired
    protected CyChannelPermissionService cyChannelPermissionService;
    @Autowired
    protected CyChannelPostPriseService cyChannelPostPriseService;
    @Autowired
    protected CyChannelPostService cyChannelPostService;
    @Autowired
    protected CyChannelRuleService cyChannelRuleService;
    @Autowired
    protected CyChannelService cyChannelService;
    @Autowired
    protected CyChannelTopicService cyChannelTopicService;
    @Autowired
    protected CyChannelPostUserService cyChannelPostUserService;
    @Autowired
    protected CyChannelPostFileService cyChannelPostFileService;

    @Autowired
    protected DmCarBrandModelService dmCarBrandModelService;
    @Autowired
    protected DmCarBrandService dmCarBrandService;
    @Autowired
    protected DmCarCheckService dmCarCheckService;
    @Autowired
    protected DmCarColorService dmCarColorService;
    @Autowired
    protected DmCarEditionService dmCarEditionService;
    @Autowired
    protected DmCarInsuranceService dmCarInsuranceService;
    @Autowired
    protected DmCarLabelService dmCarLabelService;
    @Autowired
    protected DmCarModelNoService dmCarModelNoService;
    @Autowired
    protected DmCarService dmCarService;
    @Autowired
    protected DmCarTeamService dmCarTeamService;

    @Autowired
    protected DmDriverCarService dmDriverCarService;
    @Autowired
    protected DmDriverLabelService dmDriverLabelService;
    @Autowired
    protected DmDriverPhoneService dmDriverPhoneService;
    @Autowired
    protected DmDriverPlatformService dmDriverPlatformService;
    @Autowired
    protected DmDriverService dmDriverService;
    @Autowired
    protected DmShareDriverService dmShareDriverService;

    @Autowired
    protected DmPhoneRetrievalService dmPhoneRetrievalService;
    @Autowired
    protected DmPhoneService dmPhoneService;

    @Autowired
    protected DmPlatformGmvService dmPlatformGmvService;
    @Autowired
    protected DmPlatformService dmPlatformService;

    @Autowired
    protected DmTableSortService dmTableSortService;
    @Autowired
    protected SysDictItemService sysDictItemService;
    @Autowired
    protected SysDictService sysDictService;

    @Autowired
    protected DmWorkOrderService dmWorkOrderService;
    @Autowired
    protected DmWorkOrderTransferService dmWorkOrderTransferService;
    @Autowired
    protected DmWorkOrderTypeService dmWorkOrderTypeService;
    @Autowired
    protected BillLockUtil billLockUtil;


    @Autowired
    protected RedissonDelayQueueClient redissonDelayQueueClient;

    @Autowired
    protected ChatEndpoint chatEndpoint;


    @Autowired
    protected WxProperties wxProperties;

    /**
     * 分布式锁
     * @param key
     * @return
     */
    public boolean tryLock(String key){
        return billLockUtil.lock(BillLockConstant.SAVE_ARCHIVE_INFO,key,null);
    }

    /**
     * 分布式锁 解锁
     * @param key
     */
    public void unLock(String key){
        billLockUtil.unLock(BillLockConstant.SAVE_ARCHIVE_INFO,key);
    }


    public String getPhoneCode(String phone,String pre){
        String key = "LOCKPHONE::"+phone;
        if(StringUtils.isNotEmpty(pre)){
            key = pre+"::"+key;
        }
        if(redisUtil.hasKey(key)&&redisUtil.getExpire(key)>240){
            return null;
        }
        String code = RandomUtils.phoneCodeNumber();
        code = "123456";
        /**
         * 生成的验证码存储在redis 5分钟
         */
        redisUtil.set(key,code,5*60);
        SmsWhUtil.sendSms(phone,code);
        return code;
    }

     protected  boolean checkCode(String phone,String pre,String code){
         String key = "LOCKPHONE::"+phone;
         if(StringUtils.isNotEmpty(pre)){
             key = pre+"::"+key;
         }
        if(!redisUtil.hasKey(key)){
            return false;
        }
        Object oldCode = redisUtil.get(key);
        if(!oldCode.toString().equals(code)){
            return false;
        }
        return true;
    }


    protected UserInfo getUserInfo(CyUser user){
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(user.getId());
        userInfo.setNickName(user.getNickName());
        userInfo.setAvatar(user.getAvatar());
        userInfo.setPhone(user.getPhone());
        CyAuth auth = cyAuthService.getByUserId(user.getId());
        if(auth!=null){
            userInfo.setRealname(auth.getRealname());
        }
        DefaultOrganizationInfoData data = cyOrganizationUserService.getDefaultOrganization(user.getId());
        if(data!=null){
            userInfo.setHasOrganization(true);
            userInfo.setOrganizationInfo(data);
        }else{
            CyOrganization cyOrganization = cyOrganizationService.getById(Constants.ORGANIZATION_ID);
            CyOrganizationGroup group = cyOrganizationGroupService.getDefaultGroup(Constants.ORGANIZATION_ID);
            CyOrganizationUser cyOrganizationUser = new CyOrganizationUser();
            cyOrganizationUser.setUserId(user.getId());
            cyOrganizationUser.setGroupId(group.getId());
            cyOrganizationUser.setOrganizationId(Constants.ORGANIZATION_ID);
            cyOrganizationUser.setDefaultFlag(true);
            cyOrganizationUserService.save(cyOrganizationUser);
            data = new DefaultOrganizationInfoData();
            data.setId(Constants.ORGANIZATION_ID);
            data.setIsCreateUser(user.getId().equals(cyOrganization.getCreateUserId()));
            data.setLogo(cyOrganization.getLogo());
            data.setOrganizationName(cyOrganization.getOrganizationName());
            data.setAbbreviation(cyOrganization.getAbbreviation());
            userInfo.setHasOrganization(true);
            userInfo.setOrganizationInfo(data);
        }
        return userInfo;
    }

    protected void sendMsg(CyChannelMsg msg){
        cyChannelMsgService.sendMsg(msg);
        pushChannelMsg(msg.getChannelId(),msg.getReceiveUserId(),msg.getOrganizationId());

    }

    protected void pushChannelMsg(Long channelId,Long userId,Long organizationId){
        AsyncUtil.runAsync(()->{
            ChannelListData data = cyChannelService.getChannelInfo(organizationId,userId,channelId);
            logger.error("【推送单频道消息】pushChannelMsg->:{}",JSONObject.toJSONString(data));
            if(data==null){
                return;
            }
            data.setAllMsgNum(cyChannelMsgService.getUnReadMsgNumByOrganizationId(organizationId,userId));
            MessageData messageData = new MessageData(MessageEnum.PUSH_CHANNEL_INFO,
                    JSONObject.parseObject(JSONObject.toJSONString(data)),organizationId);
            chatEndpoint.sendMessage(JSONObject.toJSONString(messageData),userId);
        });
    }

    protected void pushReadPostMsg(Long channelId,Long userId,Long organizationId){
        ChannelListData data = cyChannelService.getChannelInfo(organizationId,userId,channelId);
        logger.error("【推送单频道消息】pushReadPostMsg->:{}",JSONObject.toJSONString(data));
        if(data==null){
            return;
        }
        data.setUnReadNum(0);
        data.setAllMsgNum(cyChannelMsgService.getUnReadMsgNumByOrganizationId(organizationId,userId));
        MessageData messageData = new MessageData(MessageEnum.PUSH_CHANNEL_INFO,
                JSONObject.parseObject(JSONObject.toJSONString(data)),organizationId);
        chatEndpoint.sendMessage(JSONObject.toJSONString(messageData),userId);
    }

    protected void pushReadMsg(Long channelId,Long userId,Long organizationId){
        ChannelListData data = cyChannelService.getChannelInfo(organizationId,userId,channelId);
        logger.error("【推送单频道消息】pushReadMsg->:{}",JSONObject.toJSONString(data));
        if(data==null){
            return;
        }
        data.setMsgNum(0);
        data.setAllMsgNum(cyChannelMsgService.getUnReadMsgNumByOrganizationId(organizationId,userId));
        MessageData messageData = new MessageData(MessageEnum.PUSH_CHANNEL_INFO,
                JSONObject.parseObject(JSONObject.toJSONString(data)),organizationId);
        chatEndpoint.sendMessage(JSONObject.toJSONString(messageData),userId);
    }


    public void sendAllChannelMsg(Long channelId,Long organizationId,MessageEnum messageEnum){
        try {
            List<ChannelListData> channelList = cyChannelService.selectChannelInfoForMsg(organizationId,channelId,messageEnum);
            logger.error("【推送全用户单频道消息】channelList->:{}",channelList);
            if(CollectionUtils.isNotEmpty(channelList)){
                channelList.forEach(data->{
                    MessageData messageData = new MessageData(messageEnum,
                            JSONObject.parseObject(JSONObject.toJSONString(data)),organizationId);
                    chatEndpoint.sendMessage(JSONObject.toJSONString(messageData),data.getUserId());
                });
            }
        }catch (Exception e){
            logger.error("【推送全用户单频道消息】sendAllChannelMsg->:{}",e.getMessage());
        }

    }

}
